#include <iostream>
#include <cstring>
#include <string>
#include <cmath>
#include <algorithm>

using namespace std;

typedef long long int64;

const int maxN = 200 + 10;
const double eps = 1e-7;

struct tree_t
{
	double x, y, r;
};

struct wisp_t
{
	double x, y;
};

struct lich_t
{
	double x, y, r;
	int t;
};

lich_t	lich[maxN];
tree_t	tree[maxN];
wisp_t	wisp[maxN];
int		N, M, K;
int		visit[maxN];
int		start[maxN];
int		amount[maxN];
int		tx[maxN][maxN];
bool	reach[maxN][maxN];
double	backup_ik[maxN][maxN];
double	backup_jk[maxN][maxN];

bool dfs(int u)
{
	for (int v = 0; v < N; ++v) if (!visit[v] && reach[v][u])
	{
		visit[v] = true;
		if (start[v] < amount[v])
		{
			tx[v][start[v]++] = u;
			return 1;
		}

		for (int i = 0; i < amount[v]; ++i)
			if (dfs(tx[v][i]))
			{
				tx[v][i] = u;
				return 1;
			}
	}
	return 0;
}

int solve()
{
//	printf("limit = %d\n", limit);
	int limit = 0;
	for (int i = 0; i < N; ++i) 
	{
		start[i] = 0;
		if (lich[i].t == 0)
			amount[i] = M;
		else
			amount[i] = min(M, limit / lich[i].t + 1);
	}

	for (int j = 0; j < M; ++j)
	{
		memset(visit, 0, sizeof(visit));
		while (!dfs(j)) 
		{
			limit = 1000000000;
			for (int i = 0; i < N; ++i) if (visit[i])
				limit = min(limit, lich[i].t * amount[i]);
			for (int i = 0; i < N; ++i) 
			{
				if (lich[i].t == 0)
					amount[i] = M;
				else
					amount[i] = min(M, limit / lich[i].t + 1);
			}
			memset(visit, 0, sizeof(visit));
		}
	}

	return limit;
}

int	main()
{
	int T;
	cin >> T;

	while (T--)
	{
		cin >> N >> M >> K;
		for (int i = 0; i < N; ++i)
			cin >> lich[i].x >> lich[i].y >> lich[i].r >> lich[i].t;
		for (int i = 0; i < M; ++i)
			cin >> wisp[i].x >> wisp[i].y;
		for (int i = 0; i < K; ++i)
			cin >> tree[i].x >> tree[i].y >> tree[i].r;

		memset(reach, 0, sizeof(reach));

		for (int i = 0; i < N; ++i)
			for (int k = 0; k < K; ++k)
				backup_ik[i][k] = hypot(lich[i].x - tree[k].x, lich[i].y - tree[k].y);
		for (int j = 0; j < M; ++j)
			for (int k = 0; k < K; ++k)
				backup_jk[j][k] = hypot(wisp[j].x - tree[k].x, wisp[j].y - tree[k].y);

		for (int i = 0; i < N; ++i)
			for (int j = 0; j < M; ++j)
			{
				double x1 = -(lich[i].x - wisp[j].x);
				double y1 = -(lich[i].y - wisp[j].y);
				double d = hypot(x1, y1);
				if (d > lich[i].r + eps) continue;
				if (d < eps) 
				{
					reach[i][j] = 1;
					continue;
				}

				bool block = false;
				for (int k = 0; k < K && !block; ++k)
				{
					double x2 = -(lich[i].x - tree[k].x);
					double y2 = -(lich[i].y - tree[k].y);
					double u = backup_ik[i][k];
					double v = backup_jk[j][k];

//					printf("u = %.2lf, v = %.2lf\n", u, v);
					if (u < tree[k].r + eps) block = true;
					if (v < tree[k].r + eps) block = true;

					double x3 = x1 / d;
					double y3 = y1 / d;
					double len = x2 * x3 + y2 * y3;
//					cout  << x2 << ' ' << y2 << ", " << x3 << ' ' << y3 << endl;
//					printf("len = %.2lf\n", len);
					if (len > -eps && len < d + eps) 
					{
						double x4 = len * x3;
						double y4 = len * y3;
//						printf("x4 = %.2lf, y4 = %.2lf\n", x4, y4);
						double h = hypot(x2 - x4, y2 - y4);
						if (h < tree[k].r + eps) block = true;
					}
				}

				if (!block)
				{
					reach[i][j] = 1;
//					printf("reach : %d %d\n", i, j);
				}
			}

		bool pass = true;
		for (int j = 0; j < M; ++j)
		{
			pass = false;
			for (int i = 0; i < N; ++i) if (reach[i][j])
				pass = true;
			if (!pass) break;
		}
		if (!pass)
		{
			puts("-1");
			continue;
		}

		int answer = solve();
		cout << answer << endl;
	}
	return 0;
}
